#pragma once
//用类来封装Thread
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <string>
#include <assert.h>

class Thread;//声明

//上下文，当成一个大号的结构体
class Context
{
public:
    Thread* _this;
    void* _args;
public:
    Context()
        :_this(nullptr)
        ,_args(nullptr)
    {}
    ~Context()
    {}
};

class Thread
{
public:
    typedef std::function<void*(void*)> func_t;   
    const int num = 1024;
public:
    //线程属性（信息）的初始化（类的构造函数）+ 创建线程
    Thread(func_t func , void* args  = nullptr, int number = 0)
        :_func(func) 
        ,_args(args)
    {
        char buffer[num];
        snprintf(buffer , sizeof buffer , "thread-%d" , number);
        _name = buffer;

        //创建线程  
        Context* ctx = new Context();
        ctx->_this = this;
        ctx->_args = _args;

        int n = pthread_create(&_tid , nullptr , start_routine , ctx);//_func是C++特有的，而pthread_create是C得接口，所以这里不能使用_func
        assert( n == 0 );
        (void)n;
    }

    //传递C接口函数
    // void* start_routine(void*args)//类中有隐含的this指针，不符合pthread_create函数说要求的函数参数（void*func（void* name））
    // {
    //     return _func(args);
    // }

    static void* start_routine(void*args)
    {
        Context* ctx = static_cast<Context *>(args);
        void* ret = ctx->_this->run(ctx->_args);
        delete[] ctx;
        return ret;
    }

    //等待线程
    void join()
    {
        int n = pthread_join(_tid,nullptr);
        assert( 0 == n );
        (void)n;
    }

    //run
    void* run(void* args)
    {
        return _func(args);
    }
    ~Thread()
    {}
private:
    std::string _name;
    func_t _func;
    void* _args;    
    pthread_t _tid;

};